package com.example.analysis;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;

import android.os.Bundle;
import android.util.Log;
import android.util.Size;
import android.view.View;
import android.widget.Button;

import com.google.common.util.concurrent.ListenableFuture;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private ListenableFuture<ProcessCameraProvider> processCameraProviderListenableFuture;
    PreviewView previewView;
    Button analysisButton;
    ImageAnalysis imageAnalysis;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // onCreate 在活动被创建时被调用的。
        // 它的作用是对活动进行初始化，例如加载布局文件，设置事件监听器和初始化变量等。
        // `Bundle savedInstanceState` 参数用于保存活动状态，以便在活动被销毁后能够恢复它的状态。
        super.onCreate(savedInstanceState);
        // 将指定的布局文件加载到当前 Activity 中并显示在屏幕上。
        setContentView(R.layout.activity_main);

        // 从当前布局中查找具有指定 ID 的视图，并将其返回为 Java 对象。
        previewView = findViewById(R.id.previewView);
        analysisButton = findViewById(R.id.analysisButton);

        // 将当前类实现的 OnClickListener 接口设置为 analysisButton 的点击事件监听器，
        // 以便在单击 analysisButton 时调用类中的 onClick() 方法来处理点击事件。
        analysisButton.setOnClickListener(this);

        // 这行代码的作用是获取相机提供者的实例，它是使用 Android CameraX API 实现相机功能的关键对象之一，
        // 通过它可以获取相机设备、预览用例、图像分析用例等等，从而实现相机应用的各种功能。
        // 此代码返回一个ListenableFuture对象，用于异步获取相机提供者的实例。
        processCameraProviderListenableFuture = ProcessCameraProvider.getInstance(this);
        // 监听摄像头的准备情况。准备好时，该代码块中的 start() 方法将被调用，以便启动相机。
        processCameraProviderListenableFuture.addListener(() -> {
            try {
                ProcessCameraProvider processCameraProvider = processCameraProviderListenableFuture.get();
                start(processCameraProvider);
            } catch (ExecutionException | InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 将监听器绑定到主线程，以确保在 UI 上下文中运行该代码块。
        }, ContextCompat.getMainExecutor(this));

    }

    private void start(ProcessCameraProvider processCameraProvider) {
        // 取消当前已经绑定的摄像头设备，释放它们的资源，以便其他应用或者进程可以使用这些摄像头设备。
        // 这个方法通常在摄像头应用程序退出或者暂停时调用，以确保摄像头设备不会一直占用系统资源。
        processCameraProvider.unbindAll();

        // 创建一个相机选择器对象，并指定选择前置摄像头。
        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
                .build();

        // 创建一个相机预览对象
        // 并将其与一个 SurfaceView 组件（previewView）的 SurfaceProvider 绑定，从而在该组件上显示相机预览画面。
        Preview preview = new Preview.Builder().build();
        preview.setSurfaceProvider(previewView.getSurfaceProvider());

        // Create an ImageAnalysis object
        imageAnalysis = new ImageAnalysis.Builder()
                .setTargetResolution(new Size(1280, 720))
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                .build();

        // 在 Android 设备上启动相机，并将其与当前生命周期绑定，以便在应用程序暂停或停止时释放相机资源。
        // 该方法接受一个 `CameraSelector` 对象用于选择相机设备，一个 `Preview` 对象用于显示预览，以及一个 `imageAnalysis` 对象用于分析图像。
        processCameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis);
    }

    @Override
    public void onClick(View view) {
        // onClick(View view) 的作用是为按钮或其他视图设置点击事件处理程序。
        // 当用户点击该视图时，该方法会被调用并执行其中的代码。
        if (view.getId() == R.id.analysisButton) {
            if (analysisButton.getText() == "分析") {
                analysisButton.setText("停止");
                executeAnalysis();
            } else {
                analysisButton.setText("分析");
                imageAnalysis.clearAnalyzer();
            }

        }
    }

    private void executeAnalysis() {
        // Create an ImageAnalysis.Analyzer object
        ImageAnalysis.Analyzer analyzer = new ImageAnalysis.Analyzer() {
            @Override
            public void analyze(@NonNull ImageProxy image) {

                // Get the width and height of the image
                int width = image.getWidth();
                int height = image.getHeight();
                int format = image.getFormat();
                // Log the width and height
                Log.d("TAG", "Image analyzed with width: " + width + ", height: " + height + ", format: " + format);
                // Close the image when done
                image.close();
            }
        };

        // Set the analyzer for the ImageAnalysis object
        imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor(), analyzer);
    }
}